﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DiaosFix.Core
{
    public class UsersOperator
    {
        private DiaosFixEntities context = new DiaosFixEntities();

        public UsersOperator()
        {
            if (!context.DatabaseExists())
            {
                throw new Exception("Database not exists!");
            }
        }

        public Response<Users> FindUser(string userName)
        {
            var response = new Response<Users>();
            try
            {
                var q = context.Users.Where(p => p.Username == userName).SingleOrDefault();
                if (null != q)
                {
                    response.IsSuccess = true;
                    response.Message = string.Empty;
                    response.Item = q;
                }
                else
                {
                    response.IsSuccess = false;
                    response.Message = "user not found.";
                    response.Item = null;
                }
            }
            catch (Exception ex)
            {
                response.IsSuccess = false;
                response.Message = "shit happens, " + ex.Message;
                response.Item = null;
            }
            return response;
        }

        public Response<object> ChangePassword(string username, string oldPassword, string newPassword)
        {
            if (context.ChangePassword(username, oldPassword, newPassword) == 1)
            {
                return new Response<object>()
                {
                    IsSuccess = true,
                    Item = null,
                    Message = string.Empty
                };
            }
            else
            {
                return new Response<object>()
                {
                    IsSuccess = false,
                    Item = null,
                    Message = "0 records were updated"
                };
            }
        }

        public Response<Users> CreateUser(Users u)
        {
            // 1. Check parameters
            var response = new Response<Users>();

            if (string.IsNullOrEmpty(u.Password))
            {
                response.Message = "Password cannot be empty";
                return response;
            }
            if (string.IsNullOrEmpty(u.RealName))
            {
                response.Message = "RealName cannot be empty";
                return response;
            }
            if (string.IsNullOrEmpty(u.Username))
            {
                response.Message = "Username cannot be empty";
                return response;
            }
            if (string.IsNullOrEmpty(u.Address))
            {
                response.Message = "Address cannot be empty";
                return response;
            }
            if (string.IsNullOrEmpty(u.ContactNumber))
            {
                response.Message = "ContactNumber cannot be empty";
                return response;
            }
            if (string.IsNullOrEmpty(u.Email))
            {
                response.Message = "Email cannot be empty";
                return response;
            }

            // 2. insert into db
            try
            {
                // check if user exists
                if (!UserExists(u.Username))
                {
                    // check if user type exists
                    var qi = context.UserType.Where(p => p.Id == u.UserTypeId).SingleOrDefault();
                    if (null != qi)
                    {
                        context.AddToUsers(u);
                        if (context.SaveChanges() > 0)
                        {
                            response.IsSuccess = true;
                            response.Item = context.Users.Where(p => p.Username == u.Username).SingleOrDefault();
                        }
                        else
                        {
                            response.IsSuccess = false;
                            response.Message = "save data failed";
                            response.Item = null;
                        }
                    }
                    else
                    {
                        response.IsSuccess = false;
                        response.Message = "user type doesn't exists";
                        response.Item = null;
                    }
                }
                else
                {
                    response.IsSuccess = false;
                    response.Message = "user already exists";
                    response.Item = null;
                }
            }
            catch (Exception ex)
            {
                response.IsSuccess = false;
                response.Message = "shit happens, " + ex.Message;
                response.Item = null;
            }
            return response;
        }

        public Response<Users> Register(Users u)
        {
            // 1. Check parameters
            var response = new Response<Users>();

            if (string.IsNullOrEmpty(u.Password))
            {
                response.Message = "Password cannot be empty";
                return response;
            }
            if (string.IsNullOrEmpty(u.RealName))
            {
                response.Message = "RealName cannot be empty";
                return response;
            }
            if (string.IsNullOrEmpty(u.Username))
            {
                response.Message = "Username cannot be empty";
                return response;
            }
            if (string.IsNullOrEmpty(u.Address))
            {
                response.Message = "Address cannot be empty";
                return response;
            }
            if (string.IsNullOrEmpty(u.ContactNumber))
            {
                response.Message = "ContactNumber cannot be empty";
                return response;
            }
            if (string.IsNullOrEmpty(u.Email))
            {
                response.Message = "Email cannot be empty";
                return response;
            }

            // 2. Run procedure
            try
            {
                if (!UserExists(u.Username))
                {
                    var result = context.RegisterUser(u.Username.Trim(), u.Password.Trim(), u.RealName, u.Address, u.ContactNumber, u.Email);
                    if (result == -1)
                    {
                        response.Message = string.Format("user {0} already exists", u.Username);
                    }
                    else
                    {
                        response.IsSuccess = true;
                        response.Message = result.ToString();
                        response.Item = context.Users.Where(p => p.Username == u.Username).SingleOrDefault();
                    }
                }
                else
                {
                    response.IsSuccess = false;
                    response.Message = "user already exists";
                    response.Item = null;
                }
            }
            catch (Exception ex)
            {
                response.IsSuccess = false;
                response.Message = "shit happens, " + ex.Message;
                response.Item = null;
            }
            return response;
        }

        public bool DeleteUser(string username)
        {
            try
            {
                var q = context.Users.Where(p => p.Username == username).SingleOrDefault();
                if (null != q)
                {
                    context.DeleteObject(q);
                    if (context.SaveChanges() == 1)
                    {
                        return true;
                    }
                }
                return false;
            }
            catch
            {
                return false;
            }
        }

        public Response<Users> UpdateUserInfo(Users u)
        {
            var response = new Response<Users>();
            try
            {
                var q = context.Users.Where(p => p.Id == u.Id).SingleOrDefault();
                if (null != q)
                {
                    q.Address = u.Address;
                    q.ContactNumber = u.ContactNumber;
                    q.Email = u.Email;
                    q.Password = u.Password;
                    q.RealName = u.RealName;
                    q.Username = u.Username;
                    q.UserTypeId = u.UserTypeId;

                    if (context.SaveChanges() > 0)
                    {
                        response.IsSuccess = true;
                        response.Item = context.Users.Where(p => p.Username == u.Username).SingleOrDefault();
                    }
                    else
                    {
                        response.IsSuccess = false;
                        response.Message = "save data failed";
                        response.Item = null;
                    }
                }
                else
                {
                    response.IsSuccess = false;
                    response.Message = "user doesn't exists";
                    response.Item = null;
                }
            }
            catch (Exception ex)
            {
                response.IsSuccess = false;
                response.Message = "shit happens, " + ex.Message;
                response.Item = null;
            } 
            return response;
        }

        public Response<Users> Login(string userName, string password)
        {
            var response = new Response<Users>();

            // 1. Check parameters
            if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
            {
                response.IsSuccess = false;
                response.Message = "username or password cannot be empty";
                response.Item = null;
            }

            // 2. find in db
            try
            {

                var q = context.Users.Where(p => p.Username == userName.Trim()).SingleOrDefault();

                if (null == q)
                {
                    response.IsSuccess = false;
                    response.Message = "user does not exist";
                    response.Item = null;
                }
                else
                {
                    var qi = context.Users.Where(p => p.Username == userName && p.Password == password).SingleOrDefault();
                    if (null != qi)
                    {
                        response.IsSuccess = true;
                        response.Message = string.Empty;
                        response.Item = qi;
                    }
                    else
                    {
                        response.IsSuccess = false;
                        response.Message = "password not correct";
                        response.Item = null;
                    }
                }
            }
            catch (Exception ex)
            {
                response.IsSuccess = false;
                response.Message = "shit happens, " + ex.Message;
                response.Item = null;
            }
            return response;
        }

        public bool IsInRole(string userName, PubConstant.UserTypes userType)
        {
            if (string.IsNullOrEmpty(userName))
            {
                return false;
            }

            try
            {
                var strUserType = userType.ToString();
                var q = context.UserType.Where(p => p.Name == strUserType).SingleOrDefault();
                if (null != q)
                {
                    var qi = q.Users.Where(p => p.Username == userName).SingleOrDefault();
                    if (null != qi)
                    {
                        return true;
                    }
                }
            }
            catch (Exception)
            {
                return false;
            }
            return false;
        }

        public bool UserExists(string userName)
        {
            return null != context.Users.Where(p => p.Username == userName).SingleOrDefault();
        }
    }
}
